﻿using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace oModbus.Message
{

    /// <summary>
    /// 功能码
    /// </summary>
    public enum FunctionCode
    {
        /// <summary>
        /// 读线圈
        /// </summary>
        [Description("读线圈")] 
        ReadCoil = 0x01,
        /// <summary>
        /// 读离散量输入
        /// </summary>
        ReadDiscreteInput = 0x02,
        /// <summary>
        /// 读保持寄存器
        /// </summary>
        ReadHoldRegister = 0x03,
        /// <summary>
        /// 读输入寄存器
        /// </summary>
        ReadInputRegister = 0x04,
        /// <summary>
        /// 写单个线圈
        /// </summary>
        WriteSingleCoil = 0x05,
        /// <summary>
        /// 写单个寄存器
        /// </summary>
        WriteSingleRegister = 0x06,
        /// <summary>
        /// 写多个线圈
        /// </summary>
        WriteMultipleCoil = 0x0F,
        /// <summary>
        /// 写多个寄存器
        /// </summary>
        WriteMultipleRegister = 0x10,
        /// <summary>
        /// 读文件记录
        /// </summary>
        ReadFileRecord = 0x14,
        /// <summary>
        /// 写文件记录
        /// </summary>
        WriteFileRecord = 0x15,
        /// <summary>
        /// 屏蔽写寄存器
        /// </summary>
        MaskWriteRegister = 0x16,
        /// <summary>
        /// 读/写多个寄存器
        /// </summary>
        ReadWriteMultipleRegister = 0x17,
        /// <summary>
        /// 读设备识别码
        /// </summary>
        ReadDeviceId = 0x2B, 
        /// <summary>
        /// 异常
        /// </summary>
        Error = 0x80 
    }
    //WriteMultipleRegisterRequest
    //WriteMultipleRegisterResponse
    /// <summary>
    ///     抽象 消息
    /// </summary>
    public abstract class AbstractModbusMessage
    {
        protected AbstractModbusMessage(byte slaveAddress, FunctionCode functionCode)
        {
            SlaveAddress = slaveAddress;
            FunctionCode = functionCode;
            MessageData = new List<byte>();
        }
        protected AbstractModbusMessage(byte[] messageBytes)
        {
            // ReSharper disable once VirtualMemberCallInContructor
            Analysis(messageBytes);
        }


        /// <summary>
        /// 功能码
        /// </summary>
        public FunctionCode FunctionCode { get; protected set; }

        public byte SlaveAddress { get; protected set; }

        /// <summary>
        /// 消息  一帧数据
        /// </summary>
        public List<byte> MessageData { get; protected set; }



        /// <summary>
        /// 校验码
        /// </summary>
        public byte[] Crc { get; set; }

        /// <summary>
        /// 打包消息内容
        /// </summary>
        /// <returns></returns>
        public byte[] PackingMessage()
        {
            MessageData.Clear();
            Packing();
            var temp = new List<byte>();
            temp.AddRange(MessageData);
            temp.AddRange(Crc);
            return temp.ToArray();
        }

        protected virtual void Packing()
        {
            MessageData.Add(SlaveAddress);//地址
            MessageData.Add(Convert.ToByte((int)FunctionCode)); //功能

        }

        /// <summary>
        /// 解析
        /// </summary>
        public abstract bool Analysis(byte[] messageBytes);
    }
}
